package com.eternal.base.protocol;

import com.eternal.base.concat.DeviceModel;
import com.eternal.base.concat.DeviceSetting;
import com.eternal.base.concat.HistoryInfo;
import com.eternal.base.database.entity.History;
import com.eternal.base.database.entity.Log;
import com.eternal.base.global.BluetoothKey;
import com.eternal.base.utils.ByteUtils;
import com.eternal.base.utils.TimeUtil;
import com.eternal.framework.utils.KLog;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.TimeZone;

public class CFamilialResolution extends BaseProtocol {
    public static byte[] getSettingData(int sequence) {
        return addHead(new byte[]{
                BluetoothKey.DEVICE_TMP_UNIT,
                BluetoothKey.DEVICE_TEMP_HUM_CALIBRATION
        }, BluetoothKey.COMMAND_GET, sequence);
    }

    public static DeviceModel parseInfo(byte[] packet) {
        DeviceModel device = new DeviceModel();
        byte bt = packet[17];
        device.isDegree = !ByteUtils.getBit(bt, 1);
        device.fanState = (byte) ((ByteUtils.getBit(bt, 2)) ? 0x0 : 0x1);
        device.fan = (ByteUtils.getBit(bt, 3)) ? 0 : 1;
        device.tmpState = (byte) ByteUtils.getBits(bt, 4, 2);
        device.humState = (byte) ByteUtils.getBits(bt, 6, 2);
        device.tmp = ByteUtils.getShort(packet, 19);
        if (device.tmp != BluetoothKey.EMPTY) {
            device.tmp = device.tmp * 10;
        }
        device.hum = (packet[21] & 0xff) * 100;
        bt = packet[18];
        device.autoHighTmpSwitch = !ByteUtils.getBit(bt, 4);
        device.autoLowTmpSwitch = !ByteUtils.getBit(bt, 5);
        device.autoHighHumSwitch = !ByteUtils.getBit(bt, 6);
        device.autoLowHumSwitch = !ByteUtils.getBit(bt, 7);
        if (device.isDegree) {
            device.autoHighTmp = packet[24];
            device.autoLowTmp = packet[25];
        } else {
            device.autoHighTmp = packet[22];
            device.autoLowTmp = packet[23];
        }
        device.autoHighHum = packet[26];
        device.autoLowHum = packet[27];
        device.time = ((packet[28] & 0xff) << 16) + ((packet[29] & 0xff) << 8) + (packet[30] & 0xff);
        return device;
    }

    public static DeviceSetting parseSetting(byte[] packet) {
        DeviceSetting setting = new DeviceSetting();
        packet = check(packet);
        if (packet[0] == BluetoothKey.DEVICE_TMP_UNIT) {
            setting.isDegree = !ByteUtils.getBit(packet[2], 7);
        } else {
            return null;
        }

        if (packet[3] == BluetoothKey.DEVICE_TEMP_HUM_CALIBRATION) {
            if (setting.isDegree) {
                setting.calibrationTemperature = packet[6];
            } else {
                setting.calibrationTemperature = packet[5];
            }
            setting.calibrationHumidity = packet[7];
        } else {
            return null;
        }
        return setting;
    }

    public static byte[] getModelAlarmData(int sequence) {
        return addHead(new byte[]{BluetoothKey.DEVICE_CURRENT_TEMP_HUM_STATUS,
                        BluetoothKey.DEVICE_TMP_UNIT, BluetoothKey.DEVICE_C_MODEL_ALARM},
                BluetoothKey.COMMAND_GET, sequence);
    }

    public static byte[] setSettingData(DeviceSetting setting, int sequence) {
        byte[] data = new byte[8];
        //温度单位
        data[0] = 0x20;
        data[1] = 0x1;
        data[2] = (byte) (setting.isDegree ? 0x1 : 0x0);
        //calibration 温湿度
        data[3] = 0x24;
        data[4] = 0x3;
        data[7] = setting.calibrationHumidity;
        if (setting.isDegree) {
            data[5] = (byte) Math.round(ProtocolTransformer.getFah(setting.calibrationTemperature));
            data[6] = setting.calibrationTemperature;
        } else {
            data[5] = setting.calibrationTemperature;
            data[6] = (byte) Math.round(ProtocolTransformer.getDegree(setting.calibrationTemperature));
        }
        return addHead(data, BluetoothKey.COMMAND_SET, sequence);
    }

    public static byte[] setModelData(DeviceModel model, int sequence) {
        byte[] packet;
        if (model.isDegree) {
            packet = new byte[]{0x32, 11, 0, 0, ProtocolTransformer.getTmpSwitch(model),
                    (byte) ProtocolTransformer.getFah(model.autoHighTmp), (byte) ProtocolTransformer.getFah(model.autoLowTmp),
                    model.autoHighTmp, model.autoLowTmp,
                    model.autoHighHum, model.autoLowHum, 0, 0};
        } else {
            packet = new byte[]{0x32, 11, 0, 0, ProtocolTransformer.getTmpSwitch(model),
                    model.autoHighTmp, model.autoLowTmp,
                    (byte) ProtocolTransformer.getDegree(model.autoHighTmp), (byte) ProtocolTransformer.getDegree(model.autoLowTmp),
                    model.autoHighHum, model.autoLowHum, 0, 0};
        }
        return addHead(packet, BluetoothKey.COMMAND_SET, sequence);
    }

    public static byte[] getInfo(int sequence) {
        return addHead(new byte[]{
                BluetoothKey.COMMAND_DEVICE_C_INFO
        }, BluetoothKey.COMMAND_GET, sequence);
    }

    public static byte[] setTime(int sequence) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeZone(TimeZone.getTimeZone(TimeUtil.getCurrentTimeZone()));
        calendar.set(2020, 0, 1, 0, 0);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone(TimeUtil.getCurrentTimeZone()));
        long timtMillis = 0;
        try {
            timtMillis = Long.parseLong(TimeUtil.dateToStamp(sdf.format(calendar.getTimeInMillis())));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        long time = (System.currentTimeMillis() / 1000 - timtMillis / 1000) / 60;
//        KLog.e("时区:" + TimeUtil.getCurrentTimeZone() + "   时间戳：" + timtMillis / 1000);
        KLog.e("c set time:" + time);
        byte[] packet = new byte[]{
                BluetoothKey.DEVICE_CLOCK_TIME, 3, (byte) (time >> 16), (byte) (time >> 8), (byte) time
        };
        return addHead(packet, BluetoothKey.COMMAND_SET, sequence);
    }

    public static byte[] getHistory(int id, int size, int sequence) {
        byte[] packet = new byte[]{
                (byte) (id >> 16), (byte) (id >> 8), (byte) id, (byte) size
        };
        return addHead(packet, BluetoothKey.COMMAND_HISTORY_START, sequence);
    }

    public static int parseLogSize(byte[] packet) {
        packet = check(packet);
        if (packet[0] == BluetoothKey.COMMAND_DEVICE_C_INFO) {
            return ((packet[10] & 0xff) << 8) + (packet[11] & 0xff);
        }
        return 0;
    }

    public static List<HistoryInfo> parseHistoryInfo(byte[] packet) {
        packet = check(packet);
        List<HistoryInfo> list = new ArrayList<>();
        HistoryInfo info;
        int time;
        if (packet[0] == BluetoothKey.COMMAND_DEVICE_C_INFO) {
            for (int i = 12; i < packet.length; i += 3) {
                info = new HistoryInfo();
                info.startId = ((packet[i] & 0xff) << 16) + ((packet[i + 1] & 0xff) << 8) + (packet[i + 2] & 0xff);
                i += 3;
                info.calibrated = ((packet[i] & 0xff) << 16) + ((packet[i + 1] & 0xff) << 8) + (packet[i + 2] & 0xff);
                i += 3;
                info.length = ((packet[i] & 0xff) << 16) + ((packet[i + 1] & 0xff) << 8) + (packet[i + 2] & 0xff);
                list.add(info);
            }
        }
        int i = list.size() - 1;
        info = list.get(i);
        if (info.calibrated == 0xffffff) {
            info.calibrated = (int) ((System.currentTimeMillis() / 1000 - 1577808000) / 60 - info.length);

        }
        time = info.calibrated;
        for (int j = i - 1; j >= 0; --j) {
            info = list.get(j);
            if (info.calibrated == 0xffffff) {
                time -= info.length + 1;
                info.calibrated = time;
            } else {
                time = info.calibrated;
            }
        }
        return list;
    }

    public static byte[] getLogId(long time, int sequence) {
        return addHead(new byte[]{
                (byte) (time >> 16), (byte) (time >> 8), (byte) time
        }, BluetoothKey.COMMAND_LOG_END, sequence);
    }

    public static int parseLogId(byte[] packet) {
        packet = check(packet);
        if (packet.length == 3) {
            return ((packet[0] & 0xff) << 16) + ((packet[1] & 0xff) << 8) + (packet[2] & 0xff);
        }
        return 0;
    }

    public static byte[] getLog(int id, int size, int sequence) {
        byte[] packet = new byte[]{
                (byte) (id >> 16), (byte) (id >> 8), (byte) id, (byte) size
        };
        return addHead(packet, BluetoothKey.COMMAND_LOG, sequence);
    }

    public static Log parseLog(byte[] packet, int index) {
        Log log = new Log();
        if (packet[index] == -1 && packet[index + 1] == -1 && packet[index + 2] == -1) { // 无效数据
            return log;
        }
        log.time = ((packet[index] & 0xff) << 16) + ((packet[index + 1] & 0xff) << 8) + (packet[index + 2] & 0xff);
        log.model = (byte) ((packet[index + 3] & 0xf0) >> 4);
        switch (log.model) {
            case 1:
                log.hTmpF = packet[index + 4];
                break;
            case 2:
                log.lTmpF = packet[index + 5];
                break;
            case 3:
                log.hTmpF = packet[index + 4];
                log.lTmpF = packet[index + 5];
                break;
            case 4:
                log.hHum = packet[index + 4];
                break;
            case 5:
                log.lHum = packet[index + 5];
                break;
            case 6:
                log.hHum = packet[index + 4];
                log.lHum = packet[index + 5];
                break;
        }
//        log.tmpHum = ByteUtils.getShort(packet, index + 4);
        return log;
    }

    public static History parseHistory(byte[] packet, int index, int time) {
        History history = new History();
        history.time = time;
        history.off = false;
        history.tmp = ByteUtils.getShort(packet, index) * 10;
        history.tmp = (int) (ProtocolTransformer.getDegree(history.tmp / 100.f) * 100);
        history.hum = (char) ((((packet[index + 2] & 0xff) << 8) + (packet[index + 3] & 0xff)) * 10);
        return history;
    }
}
